package tmt.usercenter.web.controller.app;


import com.tmt.annotation.parser.EnumAnnotationParser;
import com.tmt.helper.RandomCodeHelper;
import com.tmt.sm.impl.ReturnMode;
import com.tmt.spring.validation.RegisterValidateHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.WebAsyncTask;
import tmt.usercenter.web.controller.app.bean.*;
import tmt.usercenter.web.domain.ClientSystem;
import tmt.usercenter.web.domain.SmHistory;
import tmt.usercenter.web.domain.TmtUser;
import tmt.usercenter.web.domain.enums.FuncPointType;
import tmt.usercenter.web.domain.enums.NotifyType;
import tmt.usercenter.web.domain.security.UserDetailsImpl;
import tmt.usercenter.web.service.SmHistoryService;
import tmt.usercenter.web.vo.HttpResult;

import java.text.MessageFormat;
import java.util.List;
import java.util.concurrent.Callable;

@Api(tags = "提供用户注册所需的接口集合", description = "不需要授权即可访问")
@RestController("app-register-controller")
@RequestMapping("/api/reg")
public class RegisterController extends AppBaseController {

    @Autowired
    private SmHistoryService smHistoryService;


    /**
     * 发送手机验证码，并将验证码返回客户端。
     *
     * @return
     */
    @ApiOperation(value = "手机验证码获取接口", notes = "成功返回，则时短信已经发出")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "request", value = "手机验证请求对象", required = true, paramType = "body",
                    dataType = "PhoneCheckRequest")
    })
    @RequestMapping(value = "/code", method = RequestMethod.POST)
    public WebAsyncTask<HttpResult<String>> getCheckCode(@RequestBody PhoneCheckRequest request) {

        Callable<HttpResult<String>> callable = () -> {
            //手机号码唯一性判决
            ClientSystem clientSystem = clientSystemService.findByClientId(request.getClientId());
            if (clientSystem == null)
                return HttpResult.failure("客户端ID无效");

            if (!RegisterValidateHelper.validateMobile(request.getMobile()))
                return HttpResult.failure("手机号码无效");

            if (request.getFuncPoint() == null)
                return HttpResult.failure("功能点参数无效");

            switch (request.getFuncPoint()) {
                case USER_REGISTER:
                case UPDATE_MOBILE:
                    //验证号码的唯一性或最大注册数。
                    try {
                        Long userId = request.getFuncPoint() == FuncPointType.UPDATE_MOBILE ? request.getUserId() : null;
                        uiConfigService.validateMobileRule(request.getMobile(), userId, request.getClientId());
                    } catch (Exception ex) {
                        return HttpResult.failure(ex.getMessage());
                    }
                    break;
                case CONTACT_MOBILE:
                    //收货地址中的手机号码验证。
                    break;
                default:
                    boolean exist = userService.existsByMobile(request.getMobile());
                    if (!exist) return HttpResult.failure("用户未绑定手机号码");
                    break;
            }

            //获取6位数的验证码。
            String code = RandomCodeHelper.getNumberCode(6);
            String content = MessageFormat.format("{0}{1}：{2}", clientSystem.getName(),
                    EnumAnnotationParser.getTitle(request.getFuncPoint()), code);

            HttpResult<String> result = smHistoryService.sendSm(request.getClientId(), request.getMobile(),
                    content, request.getFuncPoint(), true, ReturnMode.SYNC_MODE);

            return result.isSuccess() ? HttpResult.success(result.getMessage(), code)
                    : HttpResult.failure(result.getMessage(), null);
        };

        return new WebAsyncTask<>(callable);
    }

    @ApiOperation("用户注册接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "request", value = "新用户注册信息对象", required = true, paramType = "body",
                    dataType = "RegisterRequest")
    })
    @RequestMapping(value = "/new", method = RequestMethod.POST)
    public WebAsyncTask<HttpResult<NewUserInfo>> registerNewUser(@RequestBody RegisterRequest request) {
        Callable<HttpResult<NewUserInfo>> callable = () -> {
            //从手机APP上注册新用户。
            HttpResult<NewUserInfo> result = null;
            try {

                NewUserInfo userInfo = null;
                if (request.getUsername() == null || StringUtils.isEmpty(request.getUsername().trim())) {
                    userInfo = userService.registerUserFromApp(request);
                } else {
                    userInfo = userService.registerUserFromAppEx(request);
                }

                //通知客户端：新用户注册成功。
                if (userInfo != null) {
                    UserDetailsImpl details = userService.getUserDetailsImpl(userInfo.getId(), userInfo.getClientId());
                    clientSystemService.sendNotifyToClient(userInfo.getClientId(), NotifyType.NEW_USER, details);
                }

                result = userInfo != null ? HttpResult.success("注册成功", userInfo)
                        : HttpResult.failure("注册失败");
            } catch (Exception ex) {
                result = HttpResult.failure("注册异常：" + ex.getMessage());
            }
            return result;
        };

        return new WebAsyncTask<>(callable);
    }

    @ApiOperation("用户扫码注册接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "request", value = "用户扫码注册对象", required = true, paramType = "body",
                    dataType = "QrRegisterRequest")
    })
    @RequestMapping(value = "/new/qr", method = RequestMethod.POST)
    public WebAsyncTask<HttpResult<NewUserInfo>> registerNewUserByQrCode(@RequestBody QrRegisterRequest request) {
        Callable<HttpResult<NewUserInfo>> callable = () -> {
            //从手机APP上注册新用户。
            HttpResult<NewUserInfo> result = null;
            try {
                NewUserInfo userInfo = userService.registerUserFromAppByQrCode(request);

                //通知客户端：新用户注册成功。
                if (userInfo != null) {
                    UserDetailsImpl details = userService.getUserDetailsImpl(userInfo.getId(), userInfo.getClientId());
                    clientSystemService.sendNotifyToClient(userInfo.getClientId(), NotifyType.NEW_USER, details);
                }

                result = userInfo != null ? HttpResult.success("扫码注册成功", userInfo)
                        : HttpResult.failure("扫码注册失败");
            } catch (Exception ex) {
                ex.printStackTrace();
                result = HttpResult.failure("扫码注册异常：" + ex.getMessage());
            }
            return result;
        };

        return new WebAsyncTask<>(callable);
    }

    /**
     * 重置登录密码
     *
     * @return
     */
    @ApiOperation(value = "重置登录密码接口", notes = "重置登录密码接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "request", value = "密码重置请求对象", required = true, paramType = "body",
                    dataType = "ResetPasswordRequest")
    })
    @RequestMapping(value = "/password/reset", method = RequestMethod.POST)
    public WebAsyncTask<HttpResult<Boolean>> resetPassword(@RequestBody ResetPasswordRequest request) {

        Callable<HttpResult<Boolean>> callable = () -> {
            try {
                ClientSystem cs = clientSystemService.findByClientId(request.getClientId());
                if (cs == null)
                    return HttpResult.failure("客户端ID无效");

                if (request.getMobile() == null || StringUtils.isEmpty(request.getMobile().trim())) {
                    return HttpResult.failure("手机号码不能为空");
                }

                if (request.getCheckCode() == null || StringUtils.isEmpty(request.getCheckCode().trim())) {
                    return HttpResult.failure("验证码不能为空");
                }


                TmtUser user = null;
                if (request.getUsername() == null || StringUtils.isEmpty(request.getUsername().trim())) {
                    List<TmtUser> userList = userService.getITmtUserRepo().findAllByMobile(request.getMobile());
                    if (userList.size() == 1) {
                        user = userList.get(0);
                    } else {
                        return HttpResult.failure(userList.size() <= 0 ? "符合条件的目标账号不存在" : "符合条件的账号不唯一");
                    }
                } else {
                    user = userService.findByUsername(request.getUsername());
                }

                if (user == null)
                    return HttpResult.failure("符合条件的目标账号不存在");

                if (!RegisterValidateHelper.validatePasswordEx(request.getNewPassword()))
                    return HttpResult.failure("密码必须包含6-15位字母、数字或下划线，且同时包含大小写字母和数字");

                //先检查手机验证码是否有效。
                SmHistory history = smHistoryService.findLastValidByToMobileAndFuncPoint(request.getMobile().trim(), FuncPointType.RESET_PASSWORD);
                if (history == null || !history.getContent().contains(request.getCheckCode().trim()))
                    return HttpResult.failure("手机号码或验证码无效");

                userService.updatePassword(user.getId(), request.getNewPassword());

                smHistoryService.updateValid(history.getId(), false);

                return HttpResult.success("操作成功", true);
            } catch (Exception ex) {
                return HttpResult.failure(200, "操作失败：" + ex.getMessage(), false);
            }
        };

        return new WebAsyncTask<>(callable);
    }

}
